package com.regentsoft.cloudback.enterpriseAdmin.service.impl;

import com.regentsoft.cloudback.enterpriseAdmin.dao.ScreenMediaDao;
import com.regentsoft.cloudback.enterpriseAdmin.entity.MediaFile;
import com.regentsoft.cloudback.enterpriseAdmin.entity.ScreenMedia;
import com.regentsoft.cloudback.enterpriseAdmin.service.ExtraScreenService;
import com.regentsoft.cloudback.enterpriseAdmin.util.MediaFileManager;
import com.regentsoft.cloudback.enterpriseAdmin.vo.req.*;
import com.regentsoft.cloudback.exception.FileManagerException;
import com.regentsoft.cloudback.util.CodeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by work on 2017/11/29.
 *
 * @author lumr
 */
@Service
public class ExtraScreenServiceImpl implements ExtraScreenService {
    private final ScreenMediaDao dao;
    private final MediaFileManager fileManager;
    private final Map<String, ScreenMedia> mediaMap = new ConcurrentHashMap<>();

    @Autowired
    public ExtraScreenServiceImpl(ScreenMediaDao dao, MediaFileManager fileManager) {
        this.dao = dao;
        this.fileManager = fileManager;
    }

    @Override
    public List<ScreenMedia> getScreenMedias(MediaQueryReq query) {
        return dao.getAllMedia(query);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateMedia(MediaUploadReq req, MultipartFile file) {
        InputStream is;
        try {
            is = file.getInputStream();
        } catch (IOException e) {
            throw new FileManagerException("获取上传文件输入流错误：" + e.getMessage(), e);
        }

        if (req.isAppend()) {
            if (req.getChunk() < req.getChunks() - 1)
                return fileManager.saveTempFile(req.getCompanyId(), is, req.getFileToken());

            fileManager.saveTempFile(req.getCompanyId(), is, req.getFileToken());
        }
        final String companyId = req.getCompanyId();
        synchronized (this) {
            if (req.getFileNo() == null) {
                int count = dao.count(companyId, req.getType());
                req.setFileNo(count + 1);
            }
            ScreenMedia media = dao.get(companyId, req.getType(), req.getFileNo());
            String ext = getExtName(req.getName());
            String fileName = CodeUtil.genTOKEN().concat(ext);

            if (req.isAppend())
                fileManager.save(companyId, req.getFileToken(), fileName);
            else
                fileManager.save(companyId, is, fileName);

            if (media == null) {//insert
                media = new ScreenMedia(companyId, req.getType(), req.getFileNo(), fileName, req.getSize());
                media.setViewName(req.getViewName());
                dao.save(media);
                return true;
            } else {//update
                String oldFileName = media.getFileName();
                media.setCompanyId(companyId);
                media.setFileName(fileName);
                media.setSize(file.getSize());
                media.setViewName(req.getViewName());
                dao.update(media);
                fileManager.delete(companyId, oldFileName);
                return true;
            }
        }
    }

    @Override
    public MediaFile downloadMedia(MediaDownLoadReq req) {
        if (!req.isAppend()) {
            ScreenMedia media = dao.get(req.getCompanyId(), req.getType(), req.getFileNo());
            if (media == null)
                return null;
            return fileManager.getFileBytes(req.getCompanyId(), media.getFileName());
        }

        ScreenMedia media;
        if (req.getChunkNum() <= 1) {
            media = dao.get(req.getCompanyId(), req.getType(), req.getFileNo());
            mediaMap.put(req.getFileToken(), media);
        } else {
            if (req.getChunkNum() == req.getChunkQty())
                media = mediaMap.remove(req.getFileToken());
            else
                media = mediaMap.get(req.getFileToken());
        }
        return fileManager.getFileBytes(req.getCompanyId(), media.getFileName(), req.getStart(), req.getLength());

    }

    @Override
    public MediaFile downloadMedia(String companyId, String fileName) {
        return fileManager.getFileBytes(companyId, fileName);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, noRollbackFor = FileManagerException.class)
    public boolean deleteMedia(MediaDeleteReq req) {
        ScreenMedia media = dao.get(req.getCompanyId(), req.getType(), req.getFileNo());
        if (media == null)
            return true;
        synchronized (this) {
            dao.reSetNo(req.getCompanyId(), media.getFileNo(), media.getType());
            dao.deleteById(req.getCompanyId(), media.getId());
            fileManager.delete(req.getCompanyId(), media.getFileName());
        }
        return true;
    }

    @Override
    public String getMediaUrl(MediaBaseReq req) {
        String companyId = req.getCompanyId();
        ScreenMedia media = dao.get(req.getCompanyId(), req.getType(), req.getFileNo());
        String fileName = media.getFileName();
        return fileManager.copyFileToWeb(companyId, fileName);
    }

    @Override
    public String getMediaUrl(ScreenMedia media) {
        return fileManager.copyFileToWeb(media.getCompanyId(), media.getFileName());
    }

    /*
    获取扩展名
     */
    private String getExtName(String fileName) {
        int index = fileName.lastIndexOf(".");
        return fileName.substring(index);
    }

    private boolean insert() {
        return true;
    }

    private boolean update() {
        return true;
    }
}
